
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using Microsoft.Services.Tools.BizTalkOM;
using Microsoft.Services.Tools.BizTalkOM.Diagnostics;
using Microsoft.Win32;

namespace Microsoft.Services.Tools.BiztalkDocumenter.Core
{
    /// <summary>
    /// Summary description for Documenter.
    /// </summary>
    public class Documenter
    {
        public bool ShowOutput = true;
        public string Server = string.Empty;
        public string ResourceFolder = string.Empty;
        public string UserName = string.Empty;
        public string Password = string.Empty;
        public string Database = string.Empty;
        public string RulesServer = string.Empty;
        public string RulesDatabase = string.Empty;
        public string SsoBuild = string.Empty;
        public string SsoStage = string.Empty;
        public string SsoTest = string.Empty;
        public string SsoProd = string.Empty;
        public string[] SsoApplications = new string[] { };
        public string BizTalkXmlConfig;
        public ArrayList Applications;
        public bool IncludeReferences = true;
        public string OutputDir = @"C:\Temp";
        public string ReportName = @"";
        public PublishType PublishType;
        public IPublisher Publisher;
        public bool DocumentRules;

        public event UpdatePercentageComplete PercentageDocumentationComplete;

        /// <summary>
        /// 
        /// </summary>
        public Documenter()
        {
            SetDefaults();
        }

        public void SetDefaults()
        {
            Applications = new ArrayList();
            RegistryKey bizTalkKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\BizTalk Server\3.0");

            if (bizTalkKey != null)
            {
                string btsInstallDirectory = (string)bizTalkKey.GetValue("InstallPath", @"C:\Program Files (x86)\Microsoft BizTalk Server 2010\");

                string privateBinPath = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath;
                privateBinPath += String.Format(";{0}", Path.Combine(btsInstallDirectory, @"Tracking\Control"));
                AppDomain.CurrentDomain.SetupInformation.PrivateBinPath = privateBinPath;

                RegistryKey bizTalkAdminKey = bizTalkKey.OpenSubKey(@"Administration");

                RegistryKey bizTalkRulesKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\BusinessRules\3.0");

                if (bizTalkAdminKey != null)
                {
                    Server = (string)bizTalkAdminKey.GetValue("MgmtDBServer", Environment.MachineName);
                    Database = (string)bizTalkAdminKey.GetValue("MgmtDBName", "BizTalkMgmtDb");
                }
                if (bizTalkRulesKey != null)
                {
                    RulesServer = (string)bizTalkRulesKey.GetValue("DatabaseServer", Environment.MachineName);
                    RulesDatabase = (string)bizTalkRulesKey.GetValue("DatabaseName", "BizTalkRuleEngineDb");
                }
                OutputDir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); //Path.GetTempPath();
                ReportName = "BizTalk Documentation - " + Server;
                PublishType = PublishType.EntireConfiguration;
                //this.Publisher = new CompiledHelpPublisher();

                bizTalkKey.Close();
                if (bizTalkAdminKey != null) bizTalkAdminKey.Close();
                if (bizTalkRulesKey != null) bizTalkRulesKey.Close();
                

                //AppDomain.CurrentDomain.Load(@"Microsoft.BizTalk.XLangView");

                string dllPath = Path.Combine(btsInstallDirectory, "Tracking\\Microsoft.BizTalk.XLangView.dll");
                if(File.Exists(dllPath))
                    Assembly.LoadFrom(dllPath);
               
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void GenerateDocumentation()
        {
            try
            {
                if (Publisher == null)
                {
                    throw new ApplicationException("Error initialising documentation publisher");
                }

                Publisher.PercentageDocumentationComplete += PublisherPercentageDocumentationComplete;

                //============================================
                // Prepare the environment for the doc run
                //============================================
                if (!Publisher.Prepare())
                {
                    return;
                }

                PublisherPercentageDocumentationComplete(10);

                BizTalkInstallation bi = new BizTalkInstallation();

                if (string.Compare("localhost", Server, true) == 0 ||
                    string.Compare("(local)", Server, true) == 0 ||
                    string.Compare(".", Server, true) == 0)
                {
                    Server = Environment.GetEnvironmentVariable("COMPUTERNAME");
                }

                bi.Server = Server;
                bi.MgmtDatabaseName = Database;
                bi.RulesServer = RulesServer;
                bi.RulesDatabase = RulesDatabase;

                if (PublishType == PublishType.SpecificApplication)
                {
                    bi.LoadConfig(Applications, IncludeReferences);
                }
                else
                {
                    bi.LoadConfig();
                }

                string[] ssoLocations = {SsoBuild, SsoStage, SsoTest, SsoProd};

                Publisher.Publish(bi, PublishType, ResourceFolder, OutputDir, ReportName, DocumentRules,ssoLocations,SsoApplications,BizTalkXmlConfig);

                if (ShowOutput)
                {
                    Publisher.ShowOutput();
                }
            }
            catch (Exception ex)
            {
                TraceManager.SmartTrace.TraceError(ex);
                Console.WriteLine(ex.ToString());
                throw;
            }
            finally
            {
                //============================================
                // And cleanup - Done!
                //============================================
                if (Publisher != null)
                {
                    Publisher.Cleanup();
                }
            }

            return;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="percentage"></param>
        private void PublisherPercentageDocumentationComplete(int percentage)
        {
            if (PercentageDocumentationComplete != null)
            {
                PercentageDocumentationComplete(percentage);
            }
            return;
        }
    }
}
